package org.qloudgen.txn.dilithium.cluster.pages;

import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.wicket.AttributeModifier;
import org.apache.wicket.Session;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.AjaxSelfUpdatingTimerBehavior;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.ajax.markup.html.navigation.paging.AjaxPagingNavigator;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.FormComponent;
import org.apache.wicket.markup.html.form.Radio;
import org.apache.wicket.markup.html.form.RadioGroup;
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.PageableListView;
import org.apache.wicket.markup.html.panel.FeedbackPanel;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.apache.wicket.util.time.Duration;
import org.qloudgen.txn.dilithium.cluster.common.CommonValues;
import org.qloudgen.txn.dilithium.cluster.beans.*;
import org.qloudgen.txn.dilithium.cluster.database.ClusterImpl;
import org.qloudgen.txn.dilithium.cluster.model.ClusterModel;
import org.qloudgen.txn.dilithium.cluster.pages.common.BasePage;
import org.qloudgen.txn.dilithium.cluster.security.DilithiumSession;

import com.google.common.collect.Lists;

@SuppressWarnings("unchecked")
public class ClusterMainPage extends BasePage{

	/**
	 * @Author youngeryoyo
	 * youngeryoyo@gmail.com
	 */

	static Log log = LogFactory.getLog(ClusterMainPage.class);

	private static final long serialVersionUID = 1L;
	private transient List<Cluster> clusters = Lists.newArrayList();
	private transient ClusterModel dsm;
	private transient String buttonName;
	private transient String userNo;
	
	public ClusterMainPage(PageParameters pageParameters){
		
		super();
		this.pp = pageParameters;
	
		// hint panel
		final FeedbackPanel feedback = new FeedbackPanel("feedback");
		feedback.setOutputMarkupId(true);
		this.add(feedback);
		
		// get userNo from Login page
		userNo = ((DilithiumSession)Session.get()).getUserNo();
		
		// get userno's clusters from metadb
		ClusterImpl.getClusterList(userNo,clusters);
		
		// add form 
		Form<?> form = new Form<Object>("clusterform") {
			
			private static final long serialVersionUID = 1L;

			@Override
			protected void onSubmit() {
				
				dsm = (ClusterModel)getDefaultModelObject();
				buttonName = ((FormComponent<String>)findSubmittingButton()).getInputName();
					
				if (dsm.getGroup() == null) {
					
					info(CommonValues.INFO_CLUSTER_MAIN_PAGE_NO_CLUSTER);
					
				} else {
					
					// add buttonName  to pp
					if (pp.getPosition("buttonName") < 0 ){
						pp.add("buttonName",buttonName);
					} else {
						pp.set("buttonName",buttonName);
					}

					// add clusterID  to pp
					if (pp.getPosition("clusterID") < 0){
						pp.add("clusterID",String.valueOf(dsm.getGroup().getClusterID()));
					} else {
						pp.set("clusterID",String.valueOf(dsm.getGroup().getClusterID()));
					}
					
					processHandler();
					
				}
			
			}
			
		};
		
		form.setDefaultModel(new CompoundPropertyModel<ClusterModel>(new ClusterModel()));
		this.add(form);

		// add hello 
		form.add(new Label("hello",CommonValues.getHelloInfo(userNo)));
		
		// add group
		final RadioGroup<?> group=new RadioGroup<Object>("group"); 
		group.setOutputMarkupId(true);
		group.add(new AjaxSelfUpdatingTimerBehavior(Duration.seconds(CommonValues.CLUSTER_LIST_REFRESH_TIME)){	
			
			private static final long serialVersionUID = 1L;
			
			@Override
			protected  void	onPostProcessTarget(AjaxRequestTarget target)  {
				ClusterImpl.getClusterList(userNo,clusters);	
				target.add(group);	
			}
			
		});
		group.setRenderBodyOnly(false);
		form.add(group);
		
		// add cluster list
		final PageableListView<Cluster> listView =new PageableListView<Cluster>( "rows", clusters, CommonValues.SHOW_CLUSTER_LIST_NUMBER) {

			private static final long serialVersionUID = 1L;

			@Override
			protected void populateItem(ListItem<Cluster> item) {
				final Cluster cluster = (Cluster) item.getModelObject();
				item.add(new Radio<Cluster>("radio", new Model<Cluster>(cluster)));
				item.add( new Label( "id", String.valueOf(cluster.getClusterID())));
				item.add( new Label( "name", cluster.getClusterName()));
				item.add( new Label( "desc", cluster.getClusterDesc()));
				item.add( new Label( "status", CommonValues.statusNames.get(cluster.getClusterStatus())));
				item.add( new Label( "nodenumber", String.valueOf(cluster.getNodeNumber())));
				item.add( new Label( "controllerip", cluster.getControllerIp()));
				item.add( new Label( "gtmmasterip", cluster.getGtmMasterIp()));
				item.add( new Label( "gtmslaveip", cluster.getGtmSlaveIp()));
				item.add( new Label( "createtime", cluster.getCreateTime()));
				item.add( new Label( "starttime", cluster.getStartTime()));
				
				if (item.getIndex() % 2 == 1) {
					item.add(new AttributeModifier("class",new Model<String>("even")));
					} else {
					item.add(new AttributeModifier("class",new Model<String>("odd")));
					}
			}
		};
		listView.setOutputMarkupId(true);
		group.add(listView);
		
		// add navigator
		final AjaxPagingNavigator nav = new AjaxPagingNavigator("navigator", listView);
		nav.setOutputMarkupId(true);
		group.add(nav);
		
		// add button 
		form.add(new Button("init"));
		form.add(new Button("start"));
		form.add(new Button("stop"));
		form.add(new Button("delete"));
		form.add(new Button("add"));
		form.add(new Button("remove"));
		form.add(new Button("nodestatus"));
		form.add(new Button("config"));
		form.add(new Button("addclient"));
		form.add(new Button("removeclient"));
		
		// add refresh
		form.add(new AjaxLink<Object>("refresh"){
			private static final long serialVersionUID = 1L;
			public void onClick(AjaxRequestTarget target) {
				ClusterImpl.getClusterList(userNo,clusters);
				target.add(group);
			}
		});		
		
		// add cluster
		this.add(new BookmarkablePageLink<Object>("createcluster", CreateClusterPage.class,pp));
		
		// add logout
		form.add(new Link<Object>("logoutLink") {      
			private static final long serialVersionUID = 1L;
				public void onClick() {                 
					getSession().invalidate();                 
					getRequestCycle().setResponsePage(getApplication().getHomePage());             
				}        
		});
		
		addHeader();
		addFooter();
	}

	protected void processHandler() {

		boolean flag = true;
				
		if (buttonName.equals(CommonValues.CLUSTER_INIT)){
			
			if ( !dsm.getGroup().getClusterStatus().equals(CommonValues.STATUS_CREATE)) {
				
				info(dsm.getGroup().getClusterName() + CommonValues.INFO_CLUSTER_MAIN_PAGE_INITING);
				flag = false;
		
			}
			
	    } else if (buttonName.equals(CommonValues.CLUSTER_START)){
			
			if ( dsm.getGroup().getClusterStatus().equals(CommonValues.STATUS_ON)) {
				
				info(dsm.getGroup().getClusterName() + CommonValues.INFO_CLUSTER_MAIN_PAGE_RUNNING);
				flag = false;
				
			} else if ( dsm.getGroup().getClusterStatus().equals(CommonValues.STATUS_CREATE)) {
				
				info(dsm.getGroup().getClusterName() + CommonValues.INFO_CLUSTER_MAIN_PAGE_NO_INIT);
				flag = false;
				
			} 
			
		} else if (buttonName.equals(CommonValues.CLUSTER_STOP)){
			
			if ( dsm.getGroup().getClusterStatus().equals(CommonValues.STATUS_OFF)) {
				
				info(dsm.getGroup().getClusterName() + CommonValues.INFO_CLUSTER_MAIN_PAGE_STOPPED);
				flag = false;
				
			} else if ( dsm.getGroup().getClusterStatus().equals(CommonValues.STATUS_CREATE)) {
				
				info(dsm.getGroup().getClusterName() + CommonValues.INFO_CLUSTER_MAIN_PAGE_NO_INIT);
				flag = false;
				
			} 
			
		} else if (buttonName.equals(CommonValues.CLUSTER_DELETE)){
			
			if ( dsm.getGroup().getClusterStatus().equals(CommonValues.STATUS_ON)) {
				
				info(dsm.getGroup().getClusterName() + CommonValues.INFO_CLUSTER_MAIN_PAGE_NOT_DELETED);
				flag = false;
				
			} 
			
		} else if (buttonName.equals(CommonValues.CLUSTER_CONFIG)){
		
			setResponsePage(ShowConfPage.class, pp);
			
		} else if (buttonName.equals(CommonValues.CLUSTER_ADD_NODE)
				||buttonName.equals(CommonValues.CLUSTER_REMOVE_NODE)
				||buttonName.equals(CommonValues.CLUSTER_ADD_CLIENT)
				||buttonName.equals(CommonValues.CLUSTER_REMOVE_CLIENT)){
			
			if ( !dsm.getGroup().getClusterStatus().equals(CommonValues.STATUS_ON)) {
				
				info(dsm.getGroup().getClusterName() + CommonValues.INFO_CLUSTER_MAIN_PAGE_RUN);
				flag = false;
				
			} 
			
		}
		
		if (flag) setResponsePage(CommonValues.pages.get(buttonName), pp);		
		
	}
}
